﻿using ConfExpert.Datasets;
using ConfExpert.Forms.Depo;
using ConfExpert.Utility;

using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using DevTeam;

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace ConfExpert.Forms.Siparisler
{
    //http://anastasiosyal.com/archive/2009/01/11/18.aspx
    public partial class FuzzySearch : XPopupForm
    {
        int productId = -1;

        public int ProductId
        {
            get { return productId; }
            set { productId = value; }
        }

        public FuzzySearch()
        {
            InitializeComponent();
        }

        public FuzzySearch(string _kod)
            : this()
        {
            teKod.Text = _kod;
        }

        bool readOnly;
        public FuzzySearch(bool dummy)
            : this()
        {
            btnKartAc.Visible = btnScan.Visible = btnScanToDisk.Visible = btnToDB.Visible = labelControl1.Visible = gleAlgorithm.Visible = false;

            tabTekli.PageVisible = false;
            tabToplu.Text = "KODA göre arama";
            txtKodlar.BackColor = Color.Khaki;



            readOnly = true;
        }

        bool similar = false;
        public FuzzySearch(bool Toplu, string codes)
            : this()
        {

            btnKartAc.Visible = btnScan.Visible = btnScanToDisk.Visible = btnToDB.Visible = labelControl1.Visible = gleAlgorithm.Visible = false;

            tabTekli.PageVisible = false;
            tabToplu.Text = "KODA göre arama";
            txtKodlar.BackColor = Color.Khaki;



            readOnly = true;
            similar = true;
            txtKodlar.Text = codes;

            GetDetails("xFuzzy1;xFuzzy2", "FindSimilarTOPLU", txtKodlar.Text, "Exact");
        }


        BindingSource bsKodaGore, bsRenk, bsF1, bsF2;
        private void KumasOnerme_Load(object sender, EventArgs e)
        {
            tabRengeGore.PageVisible = false;

            //gvKodaGoreArama.ShowFindPanel();

            bsKodaGore = new BindingSource(ds, "xFindSimilar3");
            InitGridView(gvKodaGoreArama, bsKodaGore);

            bsRenk = new BindingSource(ds, "xFindSimilar2");
            InitGridView(gvRengeGoreArama, bsRenk);
            gvRengeGoreArama.Columns["Dist"].Visible = false;


            ds.xFuzzy2.Columns.Add("xProductId", typeof(int), "Iif(Selected=1,ProductId,0)");
            ds.xFuzzy2.Columns.Add("xStokGrupId", typeof(int), "Iif(Selected=1,StokGrupId,0)");
            ds.xFuzzy2.Columns.Add("xPriceEur", typeof(decimal), "Iif(Selected=1,PriceEur,0)");
            ds.xFuzzy2.Columns.Add("xKompozisyonId", typeof(int), "Iif(Selected=1,KompozisyonId,0)");

            ds.xFuzzy1.Columns["ProductId"].Expression = "MAX(Child(FK_xFuzzy2_xFuzzy1_idx1).xProductId)";
            ds.xFuzzy1.Columns["StokGrupId"].Expression = "MAX(Child(FK_xFuzzy2_xFuzzy1_idx1).xStokGrupId)";
            ds.xFuzzy1.Columns["PriceEur"].Expression = "MAX(Child(FK_xFuzzy2_xFuzzy1_idx1).xPriceEur)";
            ds.xFuzzy1.Columns["KompozisyonId"].Expression = "MAX(Child(FK_xFuzzy2_xFuzzy1_idx1).xKompozisyonId)";

            bsF1 = new BindingSource(ds, "xFuzzy1");
            bsF2 = new BindingSource(bsF1, "FK_xFuzzy2_xFuzzy1_idx1");
            InitGridView(gvTopluArama, bsF1);
            InitGridView(gvTopluAramaDetay, bsF2);

            gvTopluArama.Columns["PRO"].Visible = false;
            gvTopluArama.Columns["ProductId"].Visible = true;

            gvTopluAramaDetay.MakeColumnInvisible("idx1", "idx2", "Selected", "xStokGrupId", "xPriceEur", "xKompozisyonId");
            gvKodaGoreArama.MakeColumnInvisible("Selected", "StokGrupId", "PriceEur");

            gvTopluArama.Columns["PriceEur"].DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
            gvTopluArama.Columns["PriceEur"].DisplayFormat.FormatString = "#,###.##";

            gvTopluArama.Columns["Kod"].Caption = "Aranan";

            GridColumn col = gvKodaGoreArama.Columns["Score"];
            col.ColumnEdit = new RepositoryItemProgressBar();
            ((RepositoryItemProgressBar)col.ColumnEdit).ShowTitle = true;
            ((RepositoryItemProgressBar)col.ColumnEdit).PercentView = true;
            ((RepositoryItemProgressBar)col.ColumnEdit).Maximum = 100;

            col = gvTopluAramaDetay.Columns["Score"];
            col.ColumnEdit = new RepositoryItemProgressBar();
            ((RepositoryItemProgressBar)col.ColumnEdit).ShowTitle = true;
            ((RepositoryItemProgressBar)col.ColumnEdit).PercentView = true;
            ((RepositoryItemProgressBar)col.ColumnEdit).Maximum = 100;


            RepositoryItemHyperLinkEdit hlink = new RepositoryItemHyperLinkEdit();
            gvKodaGoreArama.Columns["Id"].ColumnEdit = hlink;
            //hlink.SingleClick = true;
            //hlink.OpenLink += new DevExpress.XtraEditors.Controls.OpenLinkEventHandler(hlink_OpenLink);

            //Qty'nin yanına yeni bir sütun ekle ve onu ProgressBar olarak göster!
            //((RepositoryItemProgressBar)col.ColumnEdit).ReadOnly = false;

            //InitCheckedComboBox(ccmb, gvOneri);

            //gvKod.OptionsView.ColumnAutoWidth = true;




            this.Shown += new EventHandler(KumasOnerme_Shown);

            gvKodaGoreArama.OptionsBehavior.Editable = false;   //hyperlinkedit bu yüzden çalışmıyor!
            gleAlgorithm.Properties.Assign(RI(Rp.Algorithm));
            gleAlgorithm.EditValue = 10; // "JaroWinkler"; değil Levenstein


            gvKodaGoreArama.DoubleClick += new System.EventHandler(this.gvOneri_DoubleClick);
            btnKartAc.Click += new EventHandler(btnKartAc_Click);

            btnAra.Click += new EventHandler(btnAra_Click);
            if (teKod.Text != string.Empty)
                btnAra.PerformClick();


            //btnScanToDisk.Click += new EventHandler(btnScanToDisk_Click);
            //btnScan.Click += new EventHandler(btnScan_Click);
            btnToDB.Click += new EventHandler(btnToDB_Click);
            btnToDB.Visible = ytk(167);

            btnScan.Visible = false; // !isDepoPersonel;
            btnScanToDisk.Visible = false;  // isDepoPersonel;





            ddlKumas.Properties.Assign(RI(Rp.V_Kumas));
            ddlRenk.EditValueChanged += new EventHandler(ceRef_EditValueChanged);
            ddlKumas.EditValueChanged += new EventHandler(sleRef_EditValueChanged);
            ddlKumas.BorderStyle = BorderStyles.Default;  //properties.assign dan kullanılması zorunlu yoksa borderless görünüyor!

            //gvRengeGoreArama.SortInfo.ClearAndAddRange(new GridColumnSortInfo[] { 
            //        new GridColumnSortInfo(gvRengeGoreArama.Columns["Dist"], ColumnSortOrder.Ascending)
            //        });

            gvRengeGoreArama.DoubleClick += new EventHandler(gvAra_DoubleClick);
            //gvRenk.Columns["DColor"].ColumnEdit = new RepositoryItemColorEdit();

            //gvAra.ActiveFilterString = "Hue > 0";

            gvKodaGoreArama.OptionsBehavior.Editable = false;
            gvRengeGoreArama.OptionsBehavior.Editable = false;

            btnAra2.Click += new EventHandler(btnAra2_Click);
            btnExact.Click += new EventHandler(btnExact_Click);
            btnFuzzy.Click += new EventHandler(btnFuzzy_Click);


            GridManager gm = GridManager.GetManager(gvTopluAramaDetay);
            gm.GridMenu.AddMenu("Eşleştir", Eslestir);

            gm = GridManager.GetManager(gvKodaGoreArama);
            gm.GridMenu.AddMenu("Seç", Sec);
            gm.GridMenu.AddMenu("Bırak", Birak);

            //gvTopluAramaDetay.OptionsView.EnableAppearanceEvenRow = gvKodaGoreArama.OptionsView.EnableAppearanceEvenRow = gvEslesen.OptionsView.EnableAppearanceEvenRow = false;
            gvTopluAramaDetay.RowStyle += new RowStyleEventHandler(gvF2_RowStyle);
            gvKodaGoreArama.RowStyle += new RowStyleEventHandler(gvF2_RowStyle);

            btnTopluKaydet.Click += new EventHandler(btnKaydet_Click);
            //btnKodaGoreKaydet.Click += new EventHandler(btnCokluSonucKaydet_Click);

            GridColumn unbColumn = gvTopluArama.Columns.AddField("Tam Eşleşme");
            unbColumn.VisibleIndex = gvTopluArama.Columns.Count;
            unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Boolean;
            unbColumn.OptionsColumn.AllowEdit = false;


            if (readOnly)
            {
                gvTopluArama.SetCaptions("idx1:ID", "ProductId:Eşleşen", "StokGrupId:Grup Stok", "PriceEur:Fiyat", "KompozisyonId:Kompozisyon");
                gvRengeGoreArama.SetCaptions("Scan:Foto");

                gvTopluArama.MakeReadOnly();
                gvRengeGoreArama.MakeReadOnly();
            }


            if (similar)
            {
                txtKodlar.Visible = false;
                gvTopluArama.Columns["Kod"].Visible = false;
            }

            gvTopluAramaDetay.BestFitColumns();
            gvTopluArama.BestFitColumns();

            tabs_SelectedPageChanged(null, null);
        }

        void btnFuzzy_Click(object sender, EventArgs e)
        {
            ds.xFuzzy2.Clear();
            ds.xFuzzy1.Clear();
            GetDetails("xFuzzy1;xFuzzy2", "FindSimilarTOPLU", txtKodlar.Text, "Fuzzy");
            gvTopluArama.BestFitColumns();
            gvTopluAramaDetay.BestFitColumns();
        }

        void btnExact_Click(object sender, EventArgs e)
        {
            ds.xFuzzy2.Clear();
            ds.xFuzzy1.Clear();
            GetDetails("xFuzzy1;xFuzzy2", "FindSimilarTOPLU", txtKodlar.Text, "Exact");
            gvTopluArama.BestFitColumns();
            gvTopluAramaDetay.BestFitColumns();
        }

        void btnKaydet_Click(object sender, EventArgs e)
        {
            bsF1.EndEdit();
            ds.xFuzzy1.AcceptChanges();
            List<int> lstr = new List<int>();
            foreach (MyData.xFuzzy1Row r in ds.xFuzzy1)
                if (!r.IsProductIdNull())
                    lstr.Add(r.ProductId);

            AppSession.SonArama = string.Join(",", lstr.ToArray());
        }

        void gvF2_RowStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs e)
        {
            if (((GridView)sender).GetRowCellValue(e.RowHandle, "Selected") != DBNull.Value)
                //e.Appearance.BackColor = Color.LightBlue;
                e.Appearance.Font = new Font(AppearanceObject.DefaultFont, FontStyle.Bold);
        }


        void Eslestir(object sender, EventArgs e)
        {
            foreach (MyData.xFuzzy2Row r in ds.xFuzzy2.Select("idx1=" + intParse(bsF1, "idx1").ToString()))
                r.SetSelectedNull();

            int idx2 = intParse(bsF2, "idx2");
            //int ProductId2 = intParse(bsF2, "ProductId");

            ds.xFuzzy2.FindByidx2(idx2).Selected = true;   // ProductId2;
        }

        void Sec(object sender, EventArgs e)
        {
            if (gvKodaGoreArama.SelectedRowsCount < 1)
                gvKodaGoreArama.SelectRow(gvKodaGoreArama.FocusedRowHandle);

            foreach (int rowHandle in gvKodaGoreArama.GetSelectedRows())
                gvKodaGoreArama.SetRowCellValue(rowHandle, gvKodaGoreArama.Columns["Selected"], true);
        }

        void Birak(object sender, EventArgs e)
        {
            if (gvKodaGoreArama.SelectedRowsCount < 1)
                gvKodaGoreArama.SelectRow(gvKodaGoreArama.FocusedRowHandle);

            foreach (int rowHandle in gvKodaGoreArama.GetSelectedRows())
                gvKodaGoreArama.SetRowCellValue(rowHandle, gvKodaGoreArama.Columns["Selected"], null);
        }


        void btnAra2_Click(object sender, EventArgs e)
        {
            if (ddlKumas.EditValue != null)
                RenkBul((int)ddlKumas.EditValue);
            else
                if (ddlRenk.EditValue != null)
                    RenkBul((Color)ddlRenk.EditValue);

        }

        BindingSource bsProduct;
        void btnToDB_Click(object sender, EventArgs e)
        {
            TAM.ProductTableAdapter = new Datasets.MyDataTableAdapters.ProductTableAdapter();
            bsProduct = new BindingSource(ds, "Product");
            AddBsToList(bsProduct);
            DirSearch(@"C:\scans");
        }

        void DirSearch(string sDir)
        {
            try
            {
                foreach (string f in Directory.GetFiles(sDir, "*.png", SearchOption.AllDirectories))
                {
                    ProductId = intParse(Path.GetFileNameWithoutExtension(f));
                    GetDetails("Product", "GetProduct", ProductId);

                    MyData.ProductRow pr = ds.Product.FindByProductId(ProductId);
                    if (pr == null)
                        XtraMessageBox.Show(ProductId.ToString());
                    else
                    {
                        //pr.PhotoLarge = ConvertImageToByteArray(Image.FromFile(f), ImageFormat.Png);
                        //pr.isProcessed = false;

                        Save();
                        ds.Product.Clear();

                        if (++turn % 10 == 0)
                            GC.Collect();
                    }
                }
                XtraMessageBox.Show("Completed");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }
        int turn = 0;

        void btnScan_Click(object sender, EventArgs e)
        {
            DoScan(false);
        }

        void btnScanToDisk_Click(object sender, EventArgs e)
        {
            DoScan(true);
        }

        private void DoScan(bool toDisk)
        {
            try
            {
                if (toDisk)
                    if (!Directory.Exists(@"C:\scans"))
                        Directory.CreateDirectory(@"C:\scans");

                if (gvKodaGoreArama.RowCount > 0)
                {

                    ProductId = (int)gvKodaGoreArama.GetFocusedRowCellValue("ProductId");
                    if (gvKodaGoreArama.GetFocusedRowCellValue("Scan") != null)
                    {
                        if (XtraMessageBox.Show("Bu varyant için daha önce taranmış bir görüntü var. Üzerine yazmak ister misiniz?", "Continue?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            Scan(toDisk);
                    }
                    else
                        Scan(toDisk);
                }
                AppSession.MainForm.RefreshData();
                gvKodaGoreArama.RefreshData();
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

        void Scan(bool toDisk)
        {
        }

        //int SaveCount = 0;
        void btnKartAc_Click(object sender, EventArgs e)
        {
            if (!teKod.Text.Contains("_"))
                XtraMessageBox.Show("Açacağınız kartın StokKodunu giriniz.");
            else
            {
                //string[] k = teKod.Text.Split("_".ToCharArray());
                ProductId = (int)ExecuteScalar("KartAc", teKod.Text, WhoAmI);
                AppSession.MainForm.RefreshData();

                btnAra.PerformClick();
            }
        }
        //1. Girilen kod, STOK kodudur (DN_Renk). Ancak yukardaki kriterlere uyması halinde, bu kod üretici veya müşteri kodundan türetilebilir. 


        void hlink_OpenLink(object sender, DevExpress.XtraEditors.Controls.OpenLinkEventArgs e)
        {
            if (e.EditValue.ToString() != string.Empty)
                using (Kodlar k = new Kodlar(intParse(e.EditValue.ToString())))
                    k.ShowDialog();
        }

        //void gvOneri_RowCellStyle(object sender, RowCellStyleEventArgs e)
        //{
        //    switch (intParse(gvKodaGoreArama.GetRowCellValue(e.RowHandle, "Tip")))
        //    {
        //        case 2:
        //            if (e.Column.FieldName == "Name" ||
        //            e.Column.FieldName == "CustomerId" ||
        //            e.Column.FieldName == "Tip"
        //            )
        //                e.Appearance.ForeColor = System.Drawing.Color.DarkViolet;
        //            break;

        //        case 3:
        //            if (e.Column.FieldName == "Name" ||
        //            e.Column.FieldName == "VendorId" ||
        //            e.Column.FieldName == "Tip"
        //            )
        //                e.Appearance.ForeColor = System.Drawing.Color.Crimson;
        //            break;
        //    }
        //}

        void KumasOnerme_Shown(object sender, EventArgs e)
        {
            if (teKod.Text == string.Empty)
                teKod.Focus();
            else
                gvKodaGoreArama.Focus();
        }

        void btnAra_Click(object sender, EventArgs e)
        {
            ds.xFindSimilar3.Clear();
            GetDetails("xFindSimilar3", "FindSimilar2", teKod.Text, intParse(gleAlgorithm.EditValue));
            gvKodaGoreArama.BestFitColumns();

            Sec(null, null);
        }

        void RenkBul(Color renk)
        {
            ds.xFindSimilar2.Clear();
            GetDetails("xFindSimilar2", "FindSimilarColor", renk.R, renk.G, renk.B);
            gvRengeGoreArama.BestFitColumns();
        }

        void RenkBul(int ProductId)
        {
            ds.xFindSimilar2.Clear();
            GetDetails("xFindSimilar2", "FindSimilarColor2", ProductId, 27);
            gvRengeGoreArama.BestFitColumns();
        }

        private void gvOneri_DoubleClick(object sender, EventArgs e)
        {
            if (gvKodaGoreArama.FocusedRowHandle > -1)
            {
                productId = Convert.ToInt32(gvKodaGoreArama.GetFocusedRowCellValue("ProductId"));

                if (gvKodaGoreArama.FocusedColumn.FieldName == "Id")
                    using (Kodlar k = new Kodlar(productId))
                        k.ShowDialog();
                else
                    this.DialogResult = DialogResult.OK;
            }
        }

        private void gvAra_DoubleClick(object sender, EventArgs e)
        {
            if (gvRengeGoreArama.FocusedRowHandle > -1)
            {
                productId = Convert.ToInt32(gvRengeGoreArama.GetFocusedRowCellValue("ProductId"));

                if (gvRengeGoreArama.FocusedColumn.FieldName == "Scan")
                    Goster(productId);
                else
                    this.DialogResult = DialogResult.OK;
            }
        }



        bool suspend2 = false;
        void sleRef_EditValueChanged(object sender, EventArgs e)
        {
            if (!suspend2)
            {
                suspend2 = true;
                ddlRenk.EditValue = null;
                RenkBul((int)ddlKumas.EditValue);
                suspend2 = false;
            }
        }

        void ceRef_EditValueChanged(object sender, EventArgs e)
        {
            if (!suspend2)
            {
                suspend2 = true;
                ddlKumas.EditValue = null;
                RenkBul((Color)ddlRenk.EditValue);
                suspend2 = false;
            }
        }


        private void chkRefRenk_CheckedChanged(object sender, EventArgs e)
        {
            ddlKumas.Visible = false;
            ddlRenk.Visible = true;
        }

        private void chkRefKumas_CheckedChanged(object sender, EventArgs e)
        {
            ddlKumas.Visible = true;
            ddlRenk.Visible = false;
        }

        private void tabs_SelectedPageChanged(object sender, DevExpress.XtraTab.TabPageChangedEventArgs e)
        {
            if (tabs.SelectedTabPage == tabRengeGore)
                FooterText = "Belli bir kumaşa ya da seçeceğiniz bir renge yakın renklerde kumaşları bulabilirsiniz.";
            else if (tabs.SelectedTabPage == tabTekli)
                FooterText = "Herhangi bir koda (Müşteri, Stok ya da Üretici) göre kumaşları bulabilirsiniz.";
            else if (tabs.SelectedTabPage == tabToplu)
                FooterText = "Aranacak kumaş listesinin herbir satırına aradığınız kumaşın herhangi bir kodunu yazarak, aradığınız kumaşları topluca bulabilirsiniz.";
        }

        private void btnOnayToplu_Click(object sender, EventArgs e)
        {
            bsF1.EndEdit();
            ds.xFuzzy1.AcceptChanges();
            List<int> lstr = new List<int>();
            foreach (MyData.xFuzzy1Row r in ds.xFuzzy1)
                if (!r.IsProductIdNull())
                    lstr.Add(r.ProductId);

            AppSession.SonArama = string.Join(",", lstr.ToArray());

            this.DialogResult = System.Windows.Forms.DialogResult.OK;

        }

        private void btnRengeGoreOnay_Click(object sender, EventArgs e)
        {
            bsRenk.EndEdit();
            ds.xFindSimilar2.AcceptChanges();
            List<int> lstr = new List<int>();
            foreach (MyData.xFindSimilar2Row r in ds.xFindSimilar2)
                lstr.Add(r.ProductId);

            AppSession.SonArama = string.Join(",", lstr.ToArray());

            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        private void gvTopluArama_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e)
        {
            if (e.Column.FieldName == "Tam Eşleşme" && e.IsGetData)
            {
                e.Value = true;
                int rh = gvTopluArama.GetRowHandle(e.ListSourceRowIndex);
                MyData.xFuzzy1Row dr = (MyData.xFuzzy1Row)gvTopluArama.GetDataRow(rh);
                if (!dr.IsProductIdNull())
                {
                    string bulunan = AppSession.Lookups.V_Kumas.FindByProductId(dr.ProductId).Name.Trim().ToLower();
                    string aranan = dr.Kod.Trim().ToLower();
                    e.Value = (aranan == bulunan);
                }
            }

        }



        //http://www.compuphase.com/cmetric.htm
        //long rmean = ( (long)r + (long)e2.r ) / 2;
        //long r = (long)r - (long)e2.r;
        //long g = (long)g - (long)e2.g;
        //long b = (long)b - (long)e2.b;
        //return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));



    }
}